Crate palette[][src]

A library that makes linear color calculations and conversion easy and accessible for anyone. It uses the type system to enforce correctness and to avoid mistakes, such as mixing incompatible color types.

It's Never "Just RGB"

Colors in, for example, images are often "gamma corrected" or stored in sRGB format as a compression method and to prevent banding. This is also a bit of a legacy from the ages of the CRT monitors, where the output from the electron gun was nonlinear. The problem is that these formats doesn't represent the actual intensities, and the compression has to be reverted to make sure that any operations on the colors are accurate. This library uses a completely linear work flow, and comes with the tools for transitioning between linear and non-linear RGB.

Adding to that, there are more than one kind of non-linear RGB. Ironically enough, this turns RGB into one of the most complex color spaces.

For example, this does not work:

// An alias for Rgb<Srgb>, which is what most pictures store.
use palette::Srgb;

let orangeish = Srgb::new(1.0, 0.6, 0.0);
let blueish = Srgb::new(0.0, 0.2, 1.0);
// let whateve_it_becomes = orangeish + blueish;

Instead, they have to be made linear before adding:

// An alias for Rgb<Srgb>, which is what most pictures store.
use palette::{Pixel, Srgb};

let orangeish = Srgb::new(1.0, 0.6, 0.0).into_linear();
let blueish = Srgb::new(0.0, 0.2, 1.0).into_linear();
let whateve_it_becomes = orangeish + blueish;

// Encode the result back into sRGB and create a byte array
let pixel: [u8; 3] = Srgb::from_linear(whateve_it_becomes)
    .into_format()
    .into_raw();

Transparency

There are many cases where pixel transparency is important, but there are also many cases where it becomes a dead weight, if it's always stored together with the color, but not used. Palette has therefore adopted a structure where the transparency component (alpha) is attachable using the Alpha type, instead of having copies of each color space.

This approach comes with the extra benefit of allowing operations to selectively affect the alpha component:

use palette::{LinSrgb, LinSrgba};

let mut c1 = LinSrgba::new(1.0, 0.5, 0.5, 0.8);
let c2 = LinSrgb::new(0.5, 1.0, 1.0);

c1.color = c1.color * c2; //Leave the alpha as it is
c1.blue += 0.2; //The color components can easily be accessed
c1 = c1 * 0.5; //Scale both the color and the alpha

A Basic Workflow

The overall workflow can be divided into three steps, where the first and last may be taken care of by other parts of the application:

Decoding -> Processing -> Encoding

1. Decoding

Find out what the source format is and convert it to a linear color space. There may be a specification, such as when working with SVG or CSS.

When working with RGB or gray scale (luma):

  • If you are asking your user to enter an RGB value, you are in a gray zone where it depends on the context. It's usually safe to assume sRGB, but sometimes it's already linear.

  • If you are decoding an image, there may be some meta data that gives you the necessary details. Otherwise it's most commonly sRGB. Usually you will end up with a slice or vector with RGB bytes, which can easily be converted to Palette colors:

use palette::{Srgb, Pixel};

// This works for any (even non-RGB) color type that can have the
// buffer element type as component.
let color_buffer: &mut [Srgb<u8>] = Pixel::from_raw_slice_mut(&mut image_buffer);
  • If you are getting your colors from the GPU, in a game or other graphical application, or if they are otherwise generated by the application, then chances are that they are already linear. Still, make sure to check that they are not being encoded somewhere.

When working with other colors:

  • For HSL, HSV, HWB: Check if they are based on any other color space than sRGB, such as Adobe or Apple RGB.

  • For any of the CIE color spaces, check for a specification of white point and light source. These are necessary for converting to RGB and other colors, that depend on perception and "viewing devices". Common defaults are the D65 light source and the sRGB white point. The Palette defaults should take you far.

2. Processing

When your color has been decoded into some Palette type, it's ready for processing. This includes things like blending, hue shifting, darkening and conversion to other formats. Just make sure that your non-linear RGB is made linear first (my_srgb.into_linear()), to make the operations available.

Different color spaced have different capabilities, pros and cons. You may have to experiment a bit (or look at the example programs) to find out what gives the desired result.

3. Encoding

When the desired processing is done, it's time to encode the colors back into some image format. The same rules applies as for the decoding, but the process reversed.

Re-exports

pub use gradient::Gradient;
pub use luma::GammaLuma;
pub use luma::GammaLumaa;
pub use luma::LinLuma;
pub use luma::LinLumaa;
pub use luma::SrgbLuma;
pub use luma::SrgbLumaa;
pub use rgb::GammaSrgb;
pub use rgb::GammaSrgba;
pub use rgb::LinSrgb;
pub use rgb::LinSrgba;
pub use rgb::Srgb;
pub use rgb::Srgba;
pub use encoding::pixel::Pixel;

Modules

blend

Color blending and blending equations.

chromatic_adaptation

Convert colors from one reference white point to another

encoding

Various encoding traits, types and standards.

gradient

Types for interpolation between multiple colors.

luma

Luminance types.

named

A collection of named color constants. Can be toggled with the "named" and "named_from_str" Cargo features.

rgb

RGB types, spaces and standards.

white_point

Defines the tristimulus values of the CIE Illuminants.

Structs

Alpha

An alpha component wrapper for colors.

Hsl

Linear HSL color space.

Hsv

Linear HSV color space.

Hwb

Linear HWB color space.

Lab

The CIE L*a*b* (CIELAB) color space.

LabHue

A hue type for the CIE L*a*b* family of color spaces.

Lch

CIE L*C*h°, a polar version of CIE L*a*b*.

RgbHue

A hue type for the RGB family of color spaces.

Xyz

The CIE 1931 XYZ color space.

Yxy

The CIE 1931 Yxy (xyY) color space.

Enums

Color

A generic color type.

Traits

Blend

A trait for colors that can be blended together.

Component

Common trait for color components.

ComponentWise

Perform a unary or binary operation on each component of a color.

FromColor

FromColor provides conversion from the colors.

GetHue

A trait for colors where a hue may be calculated.

Hue

A trait for colors where the hue can be manipulated without conversion.

IntoColor

IntoColor provides conversion to the colors.

Limited

A trait for clamping and checking if colors are within their ranges.

Mix

A trait for linear color interpolation.

Saturate

A trait for colors where the saturation (or chroma) can be manipulated without conversion.

Shade

The Shade trait allows a color to be lightened or darkened.

Type Definitions

Colora

Generic color with an alpha component. See the Colora implementation in Alpha.

Hsla

Linear HSL with an alpha component. See the Hsla implementation in Alpha.

Hsva

Linear HSV with an alpha component. See the Hsva implementation in Alpha.

Hwba

Linear HWB with an alpha component. See the Hwba implementation in Alpha.

Laba

CIE L*a*b* (CIELAB) with an alpha component. See the Laba implementation in Alpha.

Lcha

CIE L*C*h° with an alpha component. See the Lcha implementation in Alpha.

Mat3

A 9 element array representing a 3x3 matrix

Xyza

CIE 1931 XYZ with an alpha component. See the Xyza implementation in Alpha.

Yxya

CIE 1931 Yxy (xyY) with an alpha component. See the Yxya implementation in Alpha.